#!/usr/bin/python2.7

import gtk
import gobject
import Graph
import subprocess
from Project import *

from xml.dom.minidom import *
import re

dependency_regexp = "([A-Za-z0-9]+)\.(tlb|lib)'"


class DependencyNodeRenderer(gtk.CellRenderer):
    def __init__(self):
        gtk.CellRenderer.__init__(self)
        
        
        
        
      
class DependencyNode(gobject.GObject):
    def __init__(self, name):
        self.__gobject_init__()
        self.name = name
        self.commands = []
        
    
    def fill(self, dependency):
        self.name = dependency.name
        self.commands = dependency.commands
    
    def toXml(self, increment):
        xml = " " * increment + "<dependencynode name=\""+ self.name + "\">\n"
        xml += " " * increment + " <commands>\n" 
        for command in self.commands:
            xml += " " * increment + "  <command>"+command+"</command>\n"
        xml += " " * increment +" </commands>\n"
        xml += " " * increment +"</dependencynode>\n"
        return xml
        
    def fromXml(self, xml):
        doc = parseString(xml)
        dependencyNodeElement = doc.getElementsByTagName("dependencynode")[0]
        self.name = dependencyNodeElement.getAttribute('name')
        for command in dependencyNodeElement.getElementsByTagName("command"):
            self.commands.append(command.firstChild.nodeValue)
    

class DependencyGraph(Graph.Graph):
    def __init__(self):
        Graph.Graph.__init__(self)
    
    def fromXml(self, str):
        xml = xml.replace("\n", "").replace("\t", "")
        dom = parseString(xml)
        nodes = dom.getElementsByTagName("node")
        self.edges = []
        self.nodes = []
        for node in nodes:
            # Constructs project from xml
            dependency_dom = dom.getElementsByTagName("dependency")[0]
            self.index = int(node.getAttribute("index"))
            new_node = DependencyNode()
            self.addNode(new_node)
        #children = dom.getElementsByTagName("child")
        #for child in children:
        #    parent_index = int(child.getAttribute("parent"))
        #    child_index = int(child.getAttribute("child"))
        #    parent_node = self.getNodeFromIndex(parent_index)
        #    child_node = self.getNodeFromIndex(child_index)
        #    self.addEdge(parent_node, child_node)

    
class MSProject:
    def  __init__(self, filepath):
        project_dom = parse(filepath)
        project_config_nodes = project_dom.getElementsByTagName("ProjectConfiguration")
        project_libraries = project_dom.getElementsByTagName("Library")
        project_targets = project_dom.getElementsByTagName("TargetName")
        
        self.configurations = []
        self.libraries = []
        self.targets = []
            
        for config_node in project_config_nodes:
            configuration_name = config_node.getElementsByTagName("Configuration")[0].firstChild.nodeValue
            # If the config is a release
            if re.match("Release", configuration_name):
                self.configurations.append(configuration_name)
                
        for lib in project_libraries:
            lib_name = lib.getAttribute("Include").split("\\")[-1].strip()
            if not lib_name in self.libraries:
                self.libraries.append(lib_name)
      
        for target in project_targets:
            target_name = target.firstChild.nodeValue.strip()
            # If the target name is composed of a variable
            variable = re.search("\$\(([A-Za-z0-9]+)\)", target_name)
            if variable:
                #project_name = project_dom.getElementsByTagName("ProjectName")[0].firstChild.nodeValue.strip()
                project_name = filepath.split("\\")[-1].split(".")[0]
                target_name = re.sub("\$\(([A-Za-z0-9]+)\)", project_name, target_name)
            if not target_name in self.targets:
                self.targets.append(target_name)
        decomposed_filepath = filepath.split("\\")
        self.name = decomposed_filepath[-1].split(".")[0]
        self.extension = decomposed_filepath[-1].split(".")[1]
        self.path = "\\".join(decomposed_filepath[:-1])
        
        
    def getFilePath(self):
        """ returns the file path """
        return self.path + "\\" + self.name + "." + self.extension
        
        
    def commands(self):
        cmds = []
        for config in self.configurations:
            cmd = "MSBuild.exe \"" + self.getFilePath() + "\" /p:Configuration=" + config + " /m:4"
            cmds.append(cmd)
        return cmds
    
    def toXml(self):
        xml = "<commands>"
        for cmd in self.commands():
            xml += "<command>" + cmd + "</command>"
        xml += "</commands>"
        
    def compile(self):
        """ MSBuild compiler command compiles the project with the configuration "config_name" """     
        errors = []
        print "Configs=", len(self.configurations)
        for config in self.configurations:
            cmd = "MSBuild.exe \"" + self.getFilePath() + "\" /p:Configuration=" + config + " /m:4"
            print cmd
            errors = executeCommand(cmd)
            if len(errors) > 0:
                return errors
        print "End of compilation"
        return []    
            
        
    def clean(self):
        """ Cleans the project "project" with the configuration "config_name" """
        errors = []
        for config in self.configurations:
            cmd = "MSBuild.exe \"" + self.getFilePath() + "\" /p:Configuration=" + config + " /t:Clean /m:4"
            errors = executeCommand(cmd)
            if len(errors) > 0:
                return errors
        return []    
        